package com.lishe.lishe.lishe.MyRecyclerView;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.RelativeLayout;

/**
 * Created by shino on 2017/9/23.
 * 可刷新的 RecyclerView
 */

public class RefreshRecyclerView extends RecyclerView implements RecyclerviewBaseAdapter.ItemListener.ItemClickListener, RecyclerviewBaseAdapter.ItemListener.ItemLongClickListener {

    private View headerView;
    private View footerView;
    //刷新的view
    private View headerRefreshView;
    private View footerRefreshView;

    private int headerRefreshViewHeight = 0;
    private int footerRefreshViewHeight = 0;
    //刷新的view的容器
    private View headerRefreshViewContaner;
    private View footerRefreshViewContaner;
    //动画时间
    private int animationTime = 400;
    private boolean isAnimation = false;//是否在赤星动画
    private RecyclerviewBaseAdapter adapter;

    public RefreshRecyclerView(Context context) {
        super(context);
        initRefreshView();
    }

    public RefreshRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initRefreshView();
    }

    public RefreshRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initRefreshView();
    }

    /**
     * 初始化view
     */
    private void initRefreshView() {
        View headerRefreshView = new RefreshHeaderLayout(getContext());
        View footerRefreshView = new RefreshFooterLayout(getContext());
        addRefreshHeaderView(headerRefreshView);
        addRefreshFooterView(footerRefreshView);
        setOnScrollListener();
//        if(mStatus!=STATUS_DEFAULT){
//            setStatus(STATUS_DEFAULT);
//        }
    }


    //---------------------------头部和底部view------------------------------------

    public void addHeaderView(View view) {
        headerView = view;
    }

    public View getHeaderView() {
        return headerView;
    }

    public void addFooterView(View view) {
        footerView = view;
    }

    public View getFooterView() {
        return footerView;
    }

    //-----------------------------刷新的--------头部和底部view------------------------------------

    /**
     * 在未显示是计算出refreshView的高度
     *
     * @param v
     */
    public void reMeasureSoec(View v) {
        int width = MeasureSpec.makeMeasureSpec(0,
                MeasureSpec.UNSPECIFIED);
        int height = MeasureSpec.makeMeasureSpec(0,
                MeasureSpec.UNSPECIFIED);
        v.measure(width, height);
    }

    public void addRefreshHeaderView(View view) {
        if (headerRefreshViewContaner == null) {
            headerRefreshViewContaner = new RefreshContainerLayout(getContext());
        }
        headerRefreshView = view;
        reMeasureSoec(headerRefreshView);
        headerRefreshViewHeight = headerRefreshView.getMeasuredHeight();
        ((RefreshContainerLayout) headerRefreshViewContaner).removeAllViews();
        ((RefreshContainerLayout) headerRefreshViewContaner).addView(headerRefreshView);
        headerRefreshViewContaner.requestLayout();
        setHeaderRefreshEnabled(true);
    }

    public View getRefreshHeaderView() {
        return headerRefreshView;
    }

    public void addRefreshFooterView(View view) {
        if (footerRefreshViewContaner == null) {
            footerRefreshViewContaner = new RefreshContainerLayout(getContext());
        }
        footerRefreshView = view;
        reMeasureSoec(footerRefreshView);
        footerRefreshViewHeight = footerRefreshView.getMeasuredHeight();
        ((ViewGroup) footerRefreshViewContaner).removeAllViews();
        ((ViewGroup) footerRefreshViewContaner).addView(footerRefreshView);
        footerRefreshViewContaner.requestLayout();
        setFooterRefreshEnabled(false);
        footerRefreshEnabled = true;
    }

    public View getRefreshFooterView() {
        return footerRefreshView;
    }

    //--------------------本类的方法实现原recyclerview的函数,又需要可自行重写-------------------------------------
    @Override
    public void setAdapter(Adapter adapter) {
        super.setAdapter(adapter);
        //添加对应的view
        if (adapter != null && adapter instanceof RecyclerviewBaseAdapter) {
            this.adapter = (RecyclerviewBaseAdapter) adapter;
            if (headerRefreshEnabled && headerRefreshView != null) {
                ((RecyclerviewBaseAdapter) adapter).addRefreshHeaderView(headerRefreshViewContaner);
            }
            if (footerRefreshEnabled && footerRefreshView != null) {
                ((RecyclerviewBaseAdapter) adapter).addRefreshFootView(footerRefreshViewContaner);
            }
            if (headerView != null) {
                ((RecyclerviewBaseAdapter) adapter).addHeaderView(headerView);
            }
            if (footerView != null) {
                ((RecyclerviewBaseAdapter) adapter).addFootView(footerView);
            }
            ((RecyclerviewBaseAdapter) adapter).setOnItemClickListener(this);
            ((RecyclerviewBaseAdapter) adapter).setOnItemLongClickListener(this);
        } else {
            new Throwable("adapter=null 或使用RefreshRecyclerView，必须适配RecycleBaseAdapter或者其子类");
        }
    }

    @Override
    public Adapter getAdapter() {
        return super.getAdapter();
    }

    @Override
    public void setLayoutManager(LayoutManager layout) {
        super.setLayoutManager(layout);
    }

    @Override
    public int getScrollState() {
        return super.getScrollState();
    }

    @Override
    public void addItemDecoration(ItemDecoration decor, int index) {
        super.addItemDecoration(decor, index);
    }

    @Override
    public void addItemDecoration(ItemDecoration decor) {
        super.addItemDecoration(decor);
    }

    @Override
    public ItemDecoration getItemDecorationAt(int index) {
        return super.getItemDecorationAt(index);
    }


    //----------------------------------------item点击监听事件---------------------------------

    @Override
    public void OnClickListener(Adapter adapter, View view, int position) {
        if (itemClicListener != null) {
            itemClicListener.OnClickListener(adapter, view, position);
        }
    }

    @Override
    public boolean OnLongClickListener(Adapter adapter, View view, int position) {
        if (itemLongClickListener != null) {
            return itemLongClickListener.OnLongClickListener(adapter, view, position);
        }
        return false;
    }

    //接口
    ItemClickListener itemClicListener;
    ItemLongClickListener itemLongClickListener;


    public interface ItemClickListener {
        void OnClickListener(Adapter adapter, View view, int position);
    }


    public interface ItemLongClickListener {
        boolean OnLongClickListener(Adapter adapter, View view, int position);
    }

    public void setOnItemClickListener(ItemClickListener itemClicListener) {
        this.itemClicListener = itemClicListener;
        if (adapter != null) {
            ((RecyclerviewBaseAdapter) adapter).setOnItemClickListener(this);
        }
    }

    public void setOnItemLongClickListener(ItemLongClickListener itemLongClickListener) {
        this.itemLongClickListener = itemLongClickListener;
        if (adapter != null) {
            ((RecyclerviewBaseAdapter) adapter).setOnItemLongClickListener(this);
        }
    }

    //---------------------刷新view动画显示和隐藏-----------------------

    /**
     * 代码实现刷新
     */
    public void setRefreshing() {
        if (footerRefreshView != null) {
            footerRefreshView.setVisibility(GONE);
        }
        if (headerRefreshView != null) {
            if (mStatus == STATUS_DEFAULT) {
                setStatus(STATUS_START);
                if (headerRefreshEnabled) {
                    startMoveAnimation(animationTime, new DecelerateInterpolator(), 0, headerRefreshViewHeight);
                }
            } else {
                setStatus(mStatus);
            }

        }
    }

    /**
     * 结束刷新隐藏刷新的view
     */
    public void setCompleteRefresh() {
        setStatus(STATUS_END);
    }


    //--------------------------------------刷新处理-----------------------------------
    private static final String TAG = RefreshRecyclerView.class.getSimpleName();
    private static final int STATUS_DEFAULT = 0;//平常状态

    private static final int STATUS_READY = 1;//准备刷新

    private static final int STATUS_START = 2;//开始刷新

    private static final int STATUS_REFRESHING = 3;//正在刷新

    private static final int STATUS_END = 4;//结束刷新
    private static final int STATUS_LOADING_MOREING = 5;//上拉加载中
    private static final int STATUS_LOADING_MOREING_END = 6;//上拉加载结束
    private int mStatus = STATUS_DEFAULT;

    private boolean headerRefreshEnabled = true;//头部刷新功能

    private boolean footerRefreshEnabled = false;//底部部刷新功能

    public void setHeaderRefreshEnabled(boolean enabled) {
        headerRefreshEnabled = enabled;
    }

    public void setFooterRefreshEnabled(boolean enabled) {
        footerRefreshEnabled = enabled;
        if (!footerRefreshEnabled) {
            footerRefreshView.setVisibility(GONE);
            changeRefreshFooterContainerHeight(0);
        } else {
            footerRefreshView.setVisibility(VISIBLE);
        }
//        else {
//            changeRefreshFooterContainerHeight(footerRefreshViewHeight);
//        }
    }

    private void setStatus(int status) {
        mStatus = status;
        handleStatusSomthing(mStatus);
    }

    /**
     * 自定的view 如果实现RefreshRecyclerViewInterface接口，则回调相应的刷新状态
     *
     * @param v
     * @return
     */
    private boolean isCallrefresh(View v) {
        return (v != null && (v instanceof RefreshRecyclerViewInterface));
    }

    //适配不同status下的对应事件,刷新的view
    private void handleStatusSomthing(int status) {
        switch (status) {
            case STATUS_DEFAULT:
                if (isCallrefresh(headerRefreshView)) {
                    ((RefreshRecyclerViewInterface) headerRefreshView).onDefault();
                }
                if (isCallrefresh(footerRefreshView)) {
                    ((RefreshRecyclerViewInterface) footerRefreshView).onDefault();
                }
                break;
            case STATUS_READY:
                if (isCallrefresh(headerRefreshView)) {
                    ((RefreshRecyclerViewInterface) headerRefreshView).onReady();
                }
                if (isCallrefresh(footerRefreshView)) {
                    ((RefreshRecyclerViewInterface) footerRefreshView).onReady();
                }
                break;

            case STATUS_START://弹出refreshview
                setStatus(STATUS_REFRESHING);
                if (isCallrefresh(headerRefreshView)) {
                    ((RefreshRecyclerViewInterface) headerRefreshView).onStartRefresh();
                }
                if (isCallrefresh(footerRefreshView)) {
                    ((RefreshRecyclerViewInterface) footerRefreshView).onStartRefresh();
                }
                if (refreshListener != null) {
                    refreshListener.onHeaderRefresh(headerRefreshView);
                }
                break;

            case STATUS_REFRESHING:
                if (isCallrefresh(headerRefreshView)) {
                    ((RefreshRecyclerViewInterface) headerRefreshView).onRefreshing();
                }
                if (isCallrefresh(footerRefreshView)) {
                    ((RefreshRecyclerViewInterface) footerRefreshView).onRefreshing();
                }
                break;

            case STATUS_END://收起refreshview
                setStatus(STATUS_DEFAULT);
                if (isCallrefresh(headerRefreshView)) {
                    ((RefreshRecyclerViewInterface) headerRefreshView).onEndRefresh();
                }
                if (isCallrefresh(footerRefreshView)) {
                    ((RefreshRecyclerViewInterface) footerRefreshView).onEndLoadingMore();
                    ((RefreshRecyclerViewInterface) footerRefreshView).onEndRefresh();
                }
                if (headerRefreshEnabled) {
                    if (isAnimation) {
                        mScrollAnimator.cancel();
                    }
                    changeRefreshHeaderContainerHeight(0);
                }
                break;
            case STATUS_LOADING_MOREING:
                if (footerRefreshView != null) {
                    if (footerRefreshEnabled) {
                        footerRefreshView.setVisibility(VISIBLE);
                    } else {
                        footerRefreshView.setVisibility(GONE);
                    }
                }
                if (isCallrefresh(headerRefreshView)) {
                    ((RefreshRecyclerViewInterface) headerRefreshView).onLoadingMore();
                }
                if (isCallrefresh(footerRefreshView)) {
                    ((RefreshRecyclerViewInterface) footerRefreshView).onLoadingMore();
                }
                if (refreshListener != null) {
                    refreshListener.onFooterRefresh(footerRefreshView);
                }
                break;
            case STATUS_LOADING_MOREING_END:
                if (isCallrefresh(headerRefreshView)) {
                    ((RefreshRecyclerViewInterface) headerRefreshView).onEndLoadingMore();
                }
                if (isCallrefresh(footerRefreshView)) {
                    ((RefreshRecyclerViewInterface) footerRefreshView).onEndLoadingMore();
                }
                if (footerRefreshEnabled) {
                    setStatus(STATUS_DEFAULT);
                }
                break;
        }
    }

    //调节容器高度
    private void changeRefreshHeaderContainerHeight(int height) {
        if (headerRefreshViewContaner == null) {
            return;
        }
        if (headerRefreshViewContaner.getLayoutParams() == null) {
            ViewGroup.LayoutParams params = new RelativeLayout.LayoutParams(headerRefreshView.getLayoutParams());
            headerRefreshViewContaner.setLayoutParams(params);
        }
        headerRefreshViewContaner.getLayoutParams().height = height;
        headerRefreshViewContaner.requestLayout();
    }

    //调节容器高度
    private void changeRefreshFooterContainerHeight(int height) {
        if (footerRefreshViewContaner == null) {
            return;
        }
        if (footerRefreshViewContaner.getLayoutParams() == null) {
            ViewGroup.LayoutParams params = new RelativeLayout.LayoutParams(footerRefreshView.getLayoutParams());
            footerRefreshViewContaner.setLayoutParams(params);
        }
        footerRefreshViewContaner.getLayoutParams().height = height;
        footerRefreshViewContaner.requestLayout();
    }
//    AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢，在中间的时候加速
//    AccelerateInterpolator  在动画开始的地方速率改变比较慢，然后开始加速
//    AnticipateInterpolator 开始的时候向后然后向前甩
//    AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
//    BounceInterpolator   动画结束的时候弹起
//    CycleInterpolator 动画循环播放特定的次数，速率改变沿着正弦曲线
//    DecelerateInterpolator 在动画开始的地方快然后慢
//    LinearInterpolator   以常量速率改变
//    OvershootInterpolator    向前甩一定值后再回到原来位置

    private ValueAnimator mScrollAnimator;//属性动画

    /**
     * refreshview 出现和隐藏的动画
     *
     * @param time
     * @param interpolator
     * @param value
     * @param toValue
     */
    private void startMoveAnimation(final int time, final Interpolator interpolator, int value, int toValue) {
        if (mScrollAnimator == null) {
            mScrollAnimator = new ValueAnimator();
        }
        isAnimation = true;
        //cancel
        mScrollAnimator.removeAllUpdateListeners();
        mScrollAnimator.removeAllListeners();
        mScrollAnimator.cancel();
        //reset new value
        mScrollAnimator.setIntValues(value, toValue);//动画变量从value变到tovalue,要改变的属性在addUpdateListener的监听中实现如setRefreshHeaderContainerHeight函数
        mScrollAnimator.setDuration(time);//动画持续时间
        mScrollAnimator.setInterpolator(interpolator);//动画频率
        mScrollAnimator.addUpdateListener(mAnimatorUpdateListener);//动画监听这个事件在属性的值（setIntValues刷新状态值）更新时执行相应的操作
        mScrollAnimator.addListener(mAnimationListener);//动画状态监听
        mScrollAnimator.start();
    }

    //动画移动监听
    private ValueAnimator.AnimatorUpdateListener mAnimatorUpdateListener = new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            final int height = (Integer) animation.getAnimatedValue();
            changeRefreshHeaderContainerHeight(height);//
            switch (mStatus) {
                case STATUS_DEFAULT:

                    break;
                case STATUS_START:

                    break;
                case STATUS_REFRESHING:

                    break;
                case STATUS_END:

                    break;

            }
        }
    };
    //---------动画状态监听--------------
    Animator.AnimatorListener mAnimationListener = new AnimatorListenerAdapter() {
        @Override
        public void onAnimationStart(Animator animation, boolean isReverse) {
            Log.e("refreshRecyclerView", "onAnimationStart");
            isAnimation = true;
        }

        @Override
        public void onAnimationEnd(Animator animation, boolean isReverse) {
            Log.e("refreshRecyclerView", "onAnimationEnd");
            isAnimation = false;
        }
    };

    //-------------------触摸手动刷新-------------------------
    private float lastX = 0;
    private float lastY = 0;

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = e.getX();
                lastY = e.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                float moveX = e.getX();
                float moveY = e.getY();
                float x = moveX - lastX;
                float y = moveY - lastY;
                lastX = moveX;
                lastY = moveY;
                if (mStatus != STATUS_REFRESHING && mStatus != STATUS_READY) {
                    setStatus(STATUS_READY);
                }
                y = y * 0.5f + 0.5f;//控制变量的幅度(避免y0<0)
//                Log.e("ACTION_MOVE",y+"--"+headerRefreshEnabled+"-isFingerDrag()-"+isFingerDrag()+"-isShowHeaderRefresh()-"+isShowHeaderRefresh());
                if (y > 0 && y < 50 && isEnabled() && headerRefreshEnabled && isFingerDrag() && isShowHeaderRefresh() && headerRefreshView != null) {
                    float y0 = headerRefreshViewContaner.getMeasuredHeight() + y;
                    changeRefreshHeaderContainerHeight((int) y0);
                    int containLayoutH = headerRefreshViewContaner.getMeasuredHeight();
                    int refreshLayoutH = headerRefreshView.getMeasuredHeight();
                    if (isCallrefresh(headerRefreshView)) {
                        if (containLayoutH >= refreshLayoutH) {
                            ((RefreshRecyclerViewInterface) headerRefreshView).onChangeLable(true);
                        } else {
                            ((RefreshRecyclerViewInterface) headerRefreshView).onChangeLable(false);
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                int containLayoutH = headerRefreshViewContaner.getMeasuredHeight();
                int refreshLayoutH = headerRefreshView.getMeasuredHeight();
//                Log.e("ACTION_MOVE", headerRefreshEnabled + "-isShowHeaderRefresh()-" + isShowHeaderRefresh());
//                if (isEnabled() && headerRefreshEnabled && headerRefreshView != null && !isShowFooterRefresh()) {
                if (isEnabled() && headerRefreshEnabled && headerRefreshView != null) {
                    Log.e("ACTION_MOVE", containLayoutH + "-refreshLayoutH-" + refreshLayoutH);
                    if (containLayoutH >= refreshLayoutH) {//拖拽长大于刷新view的高度显示整个
                        changeRefreshHeaderContainerHeight(refreshLayoutH);
                        if (mStatus != STATUS_REFRESHING) {
                            if (footerRefreshView != null) {
                                footerRefreshView.setVisibility(GONE);
                            }
                            setStatus(STATUS_START);
                        }
                    } else {
                        Log.e("------STATUS_DEFAULT", "STATUS_DEFAULT");
                        changeRefreshHeaderContainerHeight(0);
                        setStatus(STATUS_DEFAULT);
                    }
                }
                break;
        }
        return super.onTouchEvent(e);

    }

    /**
     * 滚动到底部的判断
     *
     * @param recyclerView
     * @return
     */
    protected boolean isSlideToBottom(RecyclerView recyclerView) {
        if (recyclerView == null) return false;
        if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() >= recyclerView.computeVerticalScrollRange()) {
            return true;
        }
        return false;
    }

    /**
     * 主要用于滚动到底部后底部的加载
     */
    private void setOnScrollListener() {
        this.addOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                //newState的值1开始滑动，0停止滑动，2惯性滑动
//                Log.e("上拉加载", mStatus + "--" + isEnabled() + "--" + footerRefreshEnabled + "--" + isScrollStop() + "--"
////                        + mStatus);
                if (footerRefreshView.getVisibility() == VISIBLE && mStatus != STATUS_LOADING_MOREING && mStatus != STATUS_START && mStatus != STATUS_REFRESHING && isEnabled() && footerRefreshEnabled && footerRefreshView != null && isScrollStop() && isShowFooterRefresh()) {
                    if (footerRefreshViewContaner.getLayoutParams().height < 10) {
                        changeRefreshFooterContainerHeight(footerRefreshViewHeight);
                        int lastView = getAdapter().getItemCount();
                        RefreshRecyclerView.this.smoothScrollToPosition(lastView - 1);
                    }
                    setStatus(STATUS_LOADING_MOREING);//上拉加载
                }

            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }
        });
    }

    /**
     * @return setScrollState处理的参数主要有SCROLL_STATE_IDLE表示当前并不处于滑动状态、SCROLL_STATE_DRAGGING
     * 表示当前RecyclerView处于滑动状态（手指在屏幕上）
     * SCROLL_STATE_SETTLING 表示当前RecyclerView处于滑动状态，（手已经离开屏幕）
     * 1、该方法底层先后调用LayoutManager的onScrollStateChanged(state)方法、RecyclerView的
     * onScrollStateChanged(state)方法，最后调用RecyclerView下所有的mScrollListener域的onScrollStateChanged(state) 方法。
     */
    private boolean isFingerDrag() {
        return getScrollState() == SCROLL_STATE_DRAGGING;
    }

    private boolean isScrollStop() {
        return getScrollState() == SCROLL_STATE_IDLE;
    }

    private boolean isAutoScroll() {
        return getScrollState() == SCROLL_STATE_SETTLING;
    }

    /**
     * 滚动到顶部展示头部刷新控件
     *
     * @return
     */
    private boolean isShowHeaderRefresh() {
        Adapter adapter = getAdapter();
        if (adapter == null || adapter.getItemCount() <= 0) {
            return true;
        }
        View firstChild = getChildAt(0);
        if (firstChild instanceof RefreshContainerLayout) {
            return true;
        }
        return false;
    }

    /**
     * 滚动到底部展示底部刷新控件
     *
     * @return
     */
    private boolean isShowFooterRefresh() {
        Adapter adapter = getAdapter();
        if (adapter == null || adapter.getItemCount() <= 0) {
            return false;
        }
        int lastView = getChildCount();
        View lastChild = this.getChildAt(lastView - 1);
        if (lastChild instanceof RefreshContainerLayout) {
            return true;
        }
        return false;
    }

    //------------------------刷新的回调监听-----------------------
    private RecyclerViewRefreshListener refreshListener;

    public void setOnRefreshListener(RecyclerViewRefreshListener refreshListener) {
        this.refreshListener = refreshListener;
    }
}
